/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package serverComm;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import main.ApplicatieMain;
import model.User;
import view.MultiSpelPagina;

/**
 *
 * @author Nick
 */
public class CommIn implements Runnable {

    private final BufferedReader in;
    private final ApplicatieMain applicatieMain;
    private final CommConnection commConn;
    private Input input;

    CommIn(BufferedReader in, CommConnection commConn) {
        applicatieMain = ApplicatieMain.getInstance();
        this.in = in;
        this.commConn = commConn;


    }

    public void run() {
        listenServer();
    }

    enum Input {
        //requests made by server or opponent

        setOpponentCurrentImageAndGuessedLetters, chatMessage, requestGame, acceptGame, rejectGame,
        setWord, currentStatusChange, notifyLobbyUpdate,
        //answers to request made by client
        getLobby,
    }

    public void listenServer() {

        //Retrieve the clientId from server
        try {
            int clientId = Integer.valueOf(in.readLine());
            System.out.println("CommIn received clientId: " + clientId);
            commConn.setClientId(clientId);
        } catch (IOException ex) {
            Logger.getLogger(CommIn.class.getName()).log(Level.SEVERE, null, ex);
        }


        String inputLine;
        System.out.println("--LISTENSERVER LISTENING--");
        while (true) {

            try {

                inputLine = in.readLine();
                System.out.println("CommIn: " + inputLine);
                if (inputLine != null) {
                    
                    input = Input.valueOf(inputLine);



                    switch (input) {

                        case setOpponentCurrentImageAndGuessedLetters: {
                            int opponentImageCount = Integer.valueOf(in.readLine());
                            System.out.println("CommIn received opponentImageCount: " + opponentImageCount);
                            String opponentGuessedLetters = in.readLine();
                            System.out.println("CommIn received opponentGuessedLetters: " + opponentGuessedLetters);

                            setOpponentCurrentImageAndGuessedLetters(opponentImageCount, opponentGuessedLetters);

                            break;
                        }
                        case chatMessage: {
                            String chatMessage = in.readLine();
                            System.out.println("CommIn received chatMessage: " + chatMessage);

                            chatMessage(chatMessage);

                            break;
                        }
                        case requestGame: {
                            String opponentName = in.readLine();
                            System.out.println("CommIn received opponentName: " + opponentName);
                            int opponentId = Integer.valueOf(in.readLine());
                            System.out.println("CommIn received opponentId: " + opponentId);
                            User requestedOpponent = new User(opponentId, opponentName);

                            requestGame(requestedOpponent);

                            break;
                        }
                        case acceptGame: {
                            System.out.println("ServComm: " + applicatieMain.getRequestedOpponent().getName()
                                    + " accepted the game request");

                            acceptGame();

                            break;
                        }
                        case rejectGame: {

                            rejectGame();

                            break;
                        }
                        case setWord: {
                            String word = in.readLine();
                            System.out.println("ServComm received word: " + word);

                            setWord(word);

                            break;
                        }
                        case currentStatusChange: {

                            int statusChange = Integer.valueOf(in.readLine());
                            System.out.println("ServComm received currentStatusChange: " + statusChange);

                            currentStatusChange(statusChange);

                            break;
                        }
                        case notifyLobbyUpdate: {

                            applicatieMain.getLobby().getLobby();

                            break;
                        }
                        case getLobby: {

                            List<User> lobbyUserList = new ArrayList<User>();

                            //Receive text from server and add to lobbyUserList arraylist
                            String clientId, clientName;

                            while (!(clientId = in.readLine()).equals("END")) {
                                clientName = in.readLine();
                                System.out.println(clientName + "  ,  " + clientName.getBytes().length);
                                if (Integer.parseInt(clientId) != commConn.getClientId()) {
                                    System.out.println("RECEIVED Lobby user: ID: " + clientId + ", NAME: " + clientName);
                                    User user = new User(Integer.parseInt(clientId), clientName);
                                    lobbyUserList.add(user);
                                }

                            }

                            applicatieMain.getLobby().setLobby(lobbyUserList);

                        }
                    }
                } else {
                    System.out.println("INPUT WAS NULL");
                }
            } catch (IOException ex) {
//                commConn.disconnectServer();
            }


        }

    }

    private void setOpponentCurrentImageAndGuessedLetters(int opponentImageCount, String word) {
        applicatieMain.getMultiSpel().updateOpponentImage(opponentImageCount);
        applicatieMain.getMultiSpel().updateOpponentWord(word);
    }

    private void chatMessage(String chatMessage) {
        applicatieMain.getMultiSpel().updateChat(chatMessage);
    }

    private void requestGame(User requestedOpponent) {
        applicatieMain.setRequestedOpponent(requestedOpponent);
        applicatieMain.getLobby().requestGame(requestedOpponent.getName());
    }

    private void acceptGame() {
        applicatieMain.setNotifyLobbyUpdate(false);
        commConn.getCommOut().LeaveLobby();
    }

    private void rejectGame() {
        applicatieMain.setNotifyLobbyUpdate(true);
    }

    private void setWord(String word) {
        applicatieMain.setGalgjeWoord(word);
        //load the game screen als het nog niet aangemaakt is
        if (applicatieMain.getMultiSpel() == null) {
            MultiSpelPagina multiSpel = new MultiSpelPagina(applicatieMain.getRequestedOpponent(), false);
            applicatieMain.setMultiSpel(multiSpel);
            applicatieMain.showPage(multiSpel);
        }

        applicatieMain.getMultiSpel().nieuwSpel(false);
        commConn.getCommOut().LeaveLobby();
    }

    private void currentStatusChange(int statusChange) {
        /* Player Status
         * 1 = speler spel verlaten
         * 2 = request popup nieuw spel
         * 3 = nieuw spel (answer NEE)
         * 4 = nieuw spel (answer JA)
         * 5 = rematch (JA)
         * 6 = rematch (NEE)
         */

        switch (statusChange) {
            default: { // Onbekend result, slechte connectie, outdated version?
                break;
            }
            case 1: { // Opponent heeft spel verlaten / timeout
                // Popup verder spelen of stoppen. (verder spelen = single player)
                applicatieMain.getMultiSpel().updateChat(applicatieMain.getRequestedOpponent().getName() + " heeft het spel verlaten.");
                applicatieMain.setNieuwSpelOpponent(1);
                Object[] options = {"Verder"};
                int keuze = JOptionPane.showOptionDialog(applicatieMain.getContentPane(), applicatieMain.getRequestedOpponent().getName() + " heeft het spel verlaten.", "Lobby",
                        JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
                        null, options, options[0]);
                if (keuze == 0) {
                    commConn.disconnectServer();
                    applicatieMain.showPage(new view.SpelerOptiesPagina());
                }
                break;
            }
            case 3: { // Opponent heeft NEE gezegt op een verzoek voor een nieuw spel
                // Naar lobby
                applicatieMain.getMultiSpel().updateChat(applicatieMain.getRequestedOpponent().getName() + " heeft het spel verlaten.");
                applicatieMain.setNieuwSpelOpponent(1);
                if (applicatieMain.getNieuwSpelPlayer() != 0) {
                    Object[] options = {"Verder"};
                    int keuze = JOptionPane.showOptionDialog(applicatieMain.getContentPane(), applicatieMain.getRequestedOpponent().getName() + " heeft het spel verlaten.", "Lobby",
                            JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
                            null, options, options[0]);
                    if (keuze == 0) {
                        commConn.disconnectServer();
                        applicatieMain.showPage(new view.SpelerOptiesPagina());
                    }
                }
                break;
            }
            case 4: { // Opponent heeft JA gezegt op een verzoek voor een nieuw spel
                // Nieuw spel voor beide spelers.
                applicatieMain.getMultiSpel().updateChat(applicatieMain.getRequestedOpponent().getName() + " wil graag nog een keer spelen.");
                applicatieMain.setNieuwSpelOpponent(2);
                if (applicatieMain.getNieuwSpelPlayer() == 2) {
                    applicatieMain.getMultiSpel().nieuwSpel(true);
                }
                break;
            }
        }
    }
}
